using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Comteck.TenantSystem.Services {
  /// <summary>
  /// sqlite修复工具
  /// <para>https://geek-docs.com/sqlite/sqlite-questions/761_sqlite_better_sqlite_corruption_detection.html</para>
  /// <para>https://zhuanlan.zhihu.com/p/475687206</para>
  /// <para>https://blog.csdn.net/qq_17351077/article/details/55101919?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-55101919-blog-102929603.235^v43^pc_blog_bottom_relevance_base5&spm=1001.2101.3001.4242.2&utm_relevant_index=4</para>
  /// <para>https://blog.csdn.net/BankxiY/article/details/113696087</para>
  /// </summary>
  public class SqliteRepairHelper {

    #region 判断文件的完整性

    /// <summary>
    /// 判断文件的完整性
    /// </summary>
    /// <param name="sqlitePath"></param>
    /// <param name="dbPath"></param>
    /// <returns></returns>
    public static bool IsDbFileOk(string sqlitePath, string dbPath) {
      // no data
      if (string.IsNullOrWhiteSpace(sqlitePath) || string.IsNullOrWhiteSpace(dbPath)) {
        return true;
      }

      // 输出项
      var output = string.Empty;

      using (var p = new Process()) {
        //设置要启动的应用程序
        p.StartInfo.FileName = sqlitePath;
        p.StartInfo.Arguments = $@"""{dbPath}""";
        //是否使用操作系统shell启动
        p.StartInfo.UseShellExecute = false;
        // 接受来自调用程序的输入信息
        p.StartInfo.RedirectStandardInput = true;
        //输出信息
        p.StartInfo.RedirectStandardOutput = true;
        // 输出错误
        p.StartInfo.RedirectStandardError = true;
        //不显示程序窗口
        p.StartInfo.CreateNoWindow = true;
        //启动程序
        p.Start();

        // 执行校验命令
        p.StandardInput.WriteLine("PRAGMA integrity_check;");
        p.StandardInput.WriteLine(".quit");
        p.StandardInput.AutoFlush = true;
        p.StartInfo.StandardOutputEncoding = Encoding.UTF8;
        output = p.StandardOutput.ReadToEnd();
        p.WaitForExit();
      }

      if (!string.IsNullOrWhiteSpace(output)) {
        output = output.Replace("\r\n", "").Trim();
      }

      return "ok".Equals(output);
    }

    #endregion

    #region 修复数据库

    /// <summary>
    /// 修复数据库
    /// <para>1、database disk image is malformed</para>
    /// </summary>
    /// <param name="sqlitePath"></param>
    /// <param name="dbPath"></param>
    public static void Repair(string sqlitePath, string dbPath) {
      // no data
      if (string.IsNullOrWhiteSpace(sqlitePath) || string.IsNullOrWhiteSpace(dbPath)) {
        return;
      }

      // 输出项
      var output = string.Empty;

      using (var p = new Process()) {
        //设置要启动的应用程序
        p.StartInfo.FileName = "cmd.exe";
        //是否使用操作系统shell启动
        p.StartInfo.UseShellExecute = false;
        // 接受来自调用程序的输入信息
        p.StartInfo.RedirectStandardInput = true;
        //输出信息
        p.StartInfo.RedirectStandardOutput = true;
        // 输出错误
        p.StartInfo.RedirectStandardError = true;
        //不显示程序窗口
        p.StartInfo.CreateNoWindow = true;
        //启动程序
        p.Start();

        // 临时文件
        var tmpFile = $"{DateTime.Now.ToFileTime()}.sql";

        // 执行校验命令
        p.StandardInput.WriteLine($@"""{sqlitePath}"" ""{dbPath}"" .dump | findstr -v ""ROLLBACK"" | findstr -v ""ERROR"" > {tmpFile}");
        p.StandardInput.WriteLine($@"echo COMMIT; >> {tmpFile}");
        p.StandardInput.WriteLine($@"del ""{dbPath}""");
        p.StandardInput.WriteLine($@"""{sqlitePath}"" ""{dbPath}"" < {tmpFile}");
        p.StandardInput.WriteLine($@"del {tmpFile}");
        p.StandardInput.WriteLine($@"exit");
        p.StandardInput.AutoFlush = true;
        p.StartInfo.StandardOutputEncoding = Encoding.UTF8;
        output = p.StandardOutput.ReadToEnd();
        p.WaitForExit();
      }

      Console.WriteLine(output);
    }

    #endregion

  }
}

